package com.beantools.factory.reflect;

import java.io.Serializable;
import java.lang.reflect.Constructor;

import static com.beantools.util.ObjectUtil.isNull;

/**
 * 这是操作基本的反射类，比如获取javabean对象的无参构造器
 * 该类有一个私有构造器，不允许调用者显性地创建对象，只能通过
 * 调用{@code getInstance(Class<T> clazz)}方法创建对象。
 *
 * @author baoya
 * @version 1.0
 * @since 1.1.0
 */

public class CommonReflectFactory<T> extends AbstractReflectFactory<T> implements Serializable {

    private static final long serialVersionUID = 7908798661805591830L;

    /**
     * 这是接口的实例化对象，才用面向接口的变成方式，实现高内聚、低耦合
     */
    private static ReflectFactory instance = null;

    /**
     * 这是泛型的类字面常量
     */
    private Class<? extends T> clazz = null;

    private CommonReflectFactory(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 这是获取{@code ReflectFactory}实例化对象的的静态方法，其用
     * {@code synchronized}修饰，保证线程安全。
     *
     * @param clazz 泛型对象的类字面常量
     * @return 返回的是{@code ReflectFactory}的实例化对象
     */
    public static synchronized <T> ReflectFactory<T> getInstance(Class<T> clazz) {
        return new CommonReflectFactory<T>(clazz);
    }

    /**
     * 这是获取实例化对象的方法。如果调用者传递了当前对象的类字面的对象
     * 调用者直接将成员属性的类字面常量指向该形,{@code this.clazz = clazz}
     * 如果没有传形参，程序直接用{@code getInstance}方法中的形参
     *
     * @param clazz 泛型对象的类字面常量
     * @return 返回的是{@code Constructor}的无参构造器的对象，也就是默认构造器
     */
    @Override
    public Constructor getNoArgsConstruct(Class<? extends T> clazz) {
        if (isNull(this.clazz)) {
            this.clazz = clazz;
        }
        return super.getNoArgsConstruct(this.clazz);
    }
}
